package com.fmboy.MXH.nav.utils;

import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import cn.hutool.jwt.JWTValidator;
import com.fmboy.MXH.nav.exception.UnauthorizedException;
import jakarta.servlet.http.HttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.time.Duration;
import java.util.Date;

@Slf4j
@Component
public class JwtTool {

    private static final String USER_ID_PAYLOAD_KEY = "userId";
    private static final String EMAIL_PAYLOAD_KEY = "email";
    private static final String ROLE_PAYLOAD_KEY = "role";
    @Value("${mxh.tokenSign}")
    private String tokenSign;


    /**
     * 创建 access-token。
     *
     * @param userId 用户ID
     * @param ttl    Token的有效期
     * @return access-token 字符串
     */
    public String createToken(Integer userId, Duration ttl, String email, String role) {
        log.info("创建 JWT 用户 ID: {}", userId);
        return JWT.create()
                .setIssuedAt(new Date())
                .setExpiresAt(new Date(System.currentTimeMillis() + ttl.toMillis()))
                .setPayload(USER_ID_PAYLOAD_KEY, userId)
                .setPayload(EMAIL_PAYLOAD_KEY, email)
                .setPayload(ROLE_PAYLOAD_KEY, role)
                .setKey(tokenSign.getBytes())
                .sign();
    }

    /**
     * 解析并验证token。
     *
     * @param token 需要解析的JWT字符串
     * @return 解析得到的用户ID
     */
    public Long parseToken(String token) {
        log.info("解析和验证 JWT: {}", token);

        // 校验token是否为空
        if (token == null || token.isEmpty()) {
            throw new UnauthorizedException("未登录");
        }

        try {
            JWT jwt = JWTUtil.parseToken(token);

            // 验证签名
            if (!JWTUtil.verify(token, tokenSign.getBytes())) {
                throw new UnauthorizedException("无效的token");
            }

            // 验证过期时间
            JWTValidator.of(jwt).validateDate();

            // 获取用户ID并进行类型转换
            Object userIdObj = jwt.getPayload(USER_ID_PAYLOAD_KEY);
            if (userIdObj == null) {
                throw new UnauthorizedException("无效的token");
            }
            return convertToLong(userIdObj);

        } catch (UnauthorizedException e) {
            log.warn("无法验证 JWT: {}", e.getMessage());
            throw e;
        } catch (Exception e) {
            log.error("解析 JWT 时出现意外错误", e);
            throw new UnauthorizedException("无效的token", e);
        }
    }

    /**
     * 安全地将对象转换为Long类型。
     *
     * @param obj 要转换的对象
     * @return 转换后的Long值
     */
    private Long convertToLong(Object obj) {
        if (obj instanceof Number) {
            return ((Number) obj).longValue();
        } else if (obj instanceof String) {
            try {
                return Long.parseLong((String) obj);
            } catch (NumberFormatException e) {
                log.error("无法将字符串解析为 long", e);
                throw new UnauthorizedException("无效的token");
            }
        } else {
            throw new UnauthorizedException("无效的token");
        }
    }

    //获取用户邮箱
    public String getEmail(HttpServletRequest request) {
        JWT jwt = null;
        try {
            jwt = JWTUtil.parseToken(request.getHeader("Authorization"));
            return jwt.getPayload(EMAIL_PAYLOAD_KEY).toString();
        } catch (Exception e) {
            throw new UnauthorizedException("无法从请求头获取邮箱");
        }

    }


    // 解析 JWT 获取用户角色
    public String getRoleFromToken(HttpServletRequest request) {
        JWT jwt = null;
        try {
            jwt = JWTUtil.parseToken(request.getHeader("Authorization"));
            return jwt.getPayload(ROLE_PAYLOAD_KEY).toString();
        } catch (Exception e) {
            throw new UnauthorizedException("无法从请求头获取用户权限");
        }

    }

}